/*******************************************************************************
*                                    ZLG
*                         ----------------------------
*                         innovating embedded platform
*
* Copyright (c) 2001-2021 Guangzhou ZHIYUAN Electronics Co., Ltd.
* All rights reserved.
*
* Contact information:
* web site:    https://www.zlg.cn
*******************************************************************************/
#ifndef __HC32F4A0_GPIO_H
#define __HC32F4A0_GPIO_H

#ifdef __cplusplus
extern "C" {
#endif  /* __cplusplus*/
#include "core/include/hc32f4a0_regs_gpio.h"
#include "common/hc32f4a0_common.h"

/* \brief GPIO引脚号*/
#define GPIO_PIN_00                 (0x0001U)
#define GPIO_PIN_01                 (0x0002U)
#define GPIO_PIN_02                 (0x0004U)
#define GPIO_PIN_03                 (0x0008U)
#define GPIO_PIN_04                 (0x0010U)
#define GPIO_PIN_05                 (0x0020U)
#define GPIO_PIN_06                 (0x0040U)
#define GPIO_PIN_07                 (0x0080U)
#define GPIO_PIN_08                 (0x0100U)
#define GPIO_PIN_09                 (0x0200U)
#define GPIO_PIN_10                 (0x0400U)
#define GPIO_PIN_11                 (0x0800U)
#define GPIO_PIN_12                 (0x1000U)
#define GPIO_PIN_13                 (0x2000U)
#define GPIO_PIN_14                 (0x4000U)
#define GPIO_PIN_15                 (0x8000U)
#define GPIO_PIN_ALL                (0xFFFFU)
/* \brief GPIO引脚掩码*/
#define GPIO_PIN_MASK               (0xFFFFU)

/* \brief GPIO端口*/
#define GPIO_PORT_A                 (0x00U)
#define GPIO_PORT_B                 (0x01U)
#define GPIO_PORT_C                 (0x02U)
#define GPIO_PORT_D                 (0x03U)
#define GPIO_PORT_E                 (0x04U)
#define GPIO_PORT_F                 (0x05U)
#define GPIO_PORT_G                 (0x06U)
#define GPIO_PORT_H                 (0x07U)
#define GPIO_PORT_I                 (0x08U)

/* \brief GPIO 功能*/
#define GPIO_FUNC_18_QSPI_NSS       (GPIO_FUNC_18)    /* QSPI NSS功能 */
#define GPIO_FUNC_18_QSPI_SCK       (GPIO_FUNC_18)    /* QSPI SCK功能 */
#define GPIO_FUNC_18_QSPI_IO0       (GPIO_FUNC_18)    /* QSPI IO0功能 */
#define GPIO_FUNC_18_QSPI_IO1       (GPIO_FUNC_18)    /* QSPI IO1功能 */
#define GPIO_FUNC_18_QSPI_IO2       (GPIO_FUNC_18)    /* QSPI IO2功能 */
#define GPIO_FUNC_18_QSPI_IO3       (GPIO_FUNC_18)    /* QSPI IO3功能 */
#define GPIO_FUNC_20_USART2_TX      (GPIO_FUNC_20)    /* USART2 TX 功能*/
#define GPIO_FUNC_20_USART2_RX      (GPIO_FUNC_20)    /* USART2 RX 功能*/
#define GPIO_FUNC_32_USART1_TX      (GPIO_FUNC_32)    /* USART1 TX 功能*/
#define GPIO_FUNC_33_USART1_RX      (GPIO_FUNC_33)    /* USART1 RX 功能*/
#define GPIO_FUNC_34_USART2_TX      (GPIO_FUNC_34)    /* USART2 TX 功能 */
#define GPIO_FUNC_35_USART2_RX      (GPIO_FUNC_35)    /* USART2 RX 功能 */
#define GPIO_FUNC_36_USART6_TX      (GPIO_FUNC_36)    /* USART6 TX 功能 */
#define GPIO_FUNC_37_USART6_RX      (GPIO_FUNC_37)    /* USART6 RX 功能 */
#define GPIO_FUNC_38_USART4_TX      (GPIO_FUNC_38)    /* USART4 TX 功能 */
#define GPIO_FUNC_39_USART4_RX      (GPIO_FUNC_39)    /* USART4 RX 功能 */

/* \brief 引脚电平状态*/
#define PIN_STATE_RESET           (0U)
#define PIN_STATE_SET             (GPIO_PCR_POUT)

/* \brief 引脚方向*/
#define PIN_DIR_IN                (0U)
#define PIN_DIR_OUT               (GPIO_PCR_POUTE)

/* \brief GPIO 引脚输出类型选择*/
#define PIN_OTYPE_CMOS            (0U)
#define PIN_OTYPE_NMOS            (GPIO_PCR_NOD)

/* \brief GPIO 引脚驱动性能选择*/
#define PIN_DRV_LOW               (0U)
#define PIN_DRV_MID               (GPIO_PCR_DRV_0)
#define PIN_DRV_HIGH              (GPIO_PCR_DRV_1)

/* \brief GPIO 引脚内部上拉选择*/
#define PIN_PU_OFF                (0U)
#define PIN_PU_ON                 (GPIO_PCR_PUU)

/* \brief GPIO 引脚输出门闩选择*/
#define PIN_LATCH_OFF             (0U)
#define PIN_LATCH_ON              (GPIO_PCR_LTE)

/* \brief 引脚输出输入翻转选择*/
#define PIN_INVERT_OFF            (0U)
#define PIN_INVERT_ON             (GPIO_PCR_INVE)

/* \brief GPIO 引脚输入类型选择*/
#define PIN_ITYPE_SMT             (0U)
#define PIN_ITYPE_CMOS            (GPIO_PCR_CINSEL)

/* \brief GPIO 引脚外部中断选择*/
#define PIN_EXINT_OFF             (0U)
#define PIN_EXINT_ON              (GPIO_PCR_INTE)

/* \brief GPIO 引脚模式选择*/
#define PIN_ATTR_DIGITAL          (0U)
#define PIN_ATTR_ANALOG           (GPIO_PCR_DDIS)

/* \brief GPIO 寄存器复位值*/
#define GPIO_PSPCR_RESET_VALUE    (0x001FU)
#define GPIO_PCCR_RESET_VALUE     (0x1000U)
#define GPIO_PINAER_RESET_VALUE   (0x0000U)

/* \brief HC32F4A0 引脚副功能设置值*/
typedef enum {
    GPIO_PIN_SUBFUN_DISABLE = 0,
    GPIO_PIN_SUBFUN_ENABLE  = GPIO_PFSR_BFE,
} gpio_pin_subfun_status_t;

/* \brier 检查 引脚读等待周期 参数*/
#define IS_GPIO_READ_WAIT(wait)   (((wait) == GPIO_READ_WAIT_0) ||   \
                                   ((wait) == GPIO_READ_WAIT_1) ||   \
                                   ((wait) == GPIO_READ_WAIT_2) ||   \
                                   ((wait) == GPIO_READ_WAIT_3) ||   \
                                   ((wait) == GPIO_READ_WAIT_4) ||   \
                                   ((wait) == GPIO_READ_WAIT_5) ||   \
                                   ((wait) == GPIO_READ_WAIT_6) ||   \
                                   ((wait) == GPIO_READ_WAIT_7))
/* \brief 检查 GPIO 寄存器是否写使能 */
#define IS_GPIO_UNLOCKED()          (GPIO_PWPR_WE == (HC32F4A0_GPIO->PWPR & GPIO_PWPR_WE))

/* \brief GPIO 初始化结构体*/
struct hc32f4a0_gpio_cfg {
    uint16_t pin_sta;     /* 设置引脚高电平或低电平 */
    uint16_t pin_dir;     /* 引脚模式 */
    uint16_t pin_otype;   /* 输出类型 */
    uint16_t pin_drv;     /* 引脚驱动能力设置 */
    uint16_t latch;       /* 引脚门闩设置 */
    uint16_t pull_up;     /* 内部上拉电阻设置 */
    uint16_t invert;      /* 引脚输入输出翻转设置  */
    uint16_t pin_itype;   /* 引脚输入类型 */
    uint16_t ex_int;      /* 外部中断引脚设置 */
    uint16_t pin_attr;    /* 数字或模拟特性设置 */
};

/**
 * \brief GPIO寄存器写许可
 */
void gpio_unlock(void);
/**
 * \brief GPIO寄存器写禁止
 */
void gpio_lock(void);
/**
 * \brief GPIO 设置读等待周期
 */
int gpio_read_wait_cycle_set(uint16_t read_wait);
/**
 * \brief GPIO 配置结构体初始化
 *
 * \param[in] p_gpio_cfg 配置结构体
 */
void gpio_struct_init(struct hc32f4a0_gpio_cfg *p_gpio_cfg);
/**
 * \brief GPIO 配置
 *
 * \param[in] port       要初始化的端口
 * \param[in] pin        要初始化的引脚
 * \param[in] p_gpio_cfg 要配置的参数
 *
 * \retval 成功返回0
 */
int gpio_cfg(uint8_t                   port,
             uint16_t                  pin,
             struct hc32f4a0_gpio_cfg *p_gpio_cfg);
/**
 * \brief GPIO 反初始化
 */
void gpio_deinit(uint8_t port, uint16_t pin);
/**
 * \brief GPIO 功能设置
 *
 * \param[in] port GPIO 端口
 * \param[in] pin  GPIO 引脚
 * \param[in] func 要设置的功能
 * \param[in] bfe  是否使能副功能
 *
 * \retval 成功返回 0
 */
int gpio_func_set(uint8_t  port,
                  uint16_t pin,
                  uint8_t  func,
                  uint16_t bfe);
/**
 * \brief 获取 GPIO 引脚的状态
 */
int gpio_sta_get(uint8_t port, uint16_t pin, uint8_t *p_sta);
/**
 * \brief 设置 GPIO 引脚的状态
 */
int gpio_sta_set(uint8_t port, uint16_t pin, uint8_t sta);
/**
 * \brief GPIO 引脚的状态翻转
 */
int gpio_sta_toggle(uint8_t port, uint16_t pin);
#ifdef __cplusplus
}
#endif  /* __cplusplus  */


#endif



